package comm;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.Properties;

// main类
public class Main {

	public static void main(String[] args) {
		Log.println("main启动");
		try {
			printPid();
			// 初始化
			// 检查服务文件是否齐全
			String[] files = { PropertyManager.DefaultConfigFile, "./logfile" };
			for (int i = 0; i < files.length; i++) {
				if (false == (new File(files[i])).exists()) {
					Log.println(files[i] + "文件不存在，退出");
					return;
				}
			}

			// 启动通信服务
			MainLoop mainLoop = new MainLoop(); // 创建主循环线程
			mainLoop.start();
			Log.println("SystemFileEncoding:" + PropertyManager.SystemFileEncoding);
		} catch (Exception e) {
			Log.println(e.toString());
		}

	}

	static void printPid() {
		// 获取当前进程ID
		final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
		final String info = runtime.getName();
		// System.out.println(info);
		final int index = info.indexOf("@");
		if (index != -1) {
			final int pid = Integer.parseInt(info.substring(0, index));
			System.out.println("当前进程pid:" + pid);
			Log.println("当前进程pid:" + pid);
		}
	}

}

// 配置文件管理类
// 封装了Properties类，并包含一些全局配置信息
// 应保证出现异常时能返回默认字符串
class PropertyManager {
	final static String CharSet = "UTF-8"; // 服务器统一编码
	final static String SystemFileEncoding = System.getProperty("file.encoding"); // 系统默认文件编码
	final static String DefaultConfigFile = "./CommServer-Config.properties"; // 默认配置文件

	static String getProtery(final String aKey, final String aDefaultValue) {
		return getProtery(aKey, aDefaultValue, PropertyManager.DefaultConfigFile);
	}

	static int getInt(final String aKey, final int aDefaultValue) {
		String strNum = PropertyManager.getProtery(aKey, Integer.toString(aDefaultValue));
		int newNum = aDefaultValue;
		try {
			newNum = Integer.parseInt(strNum);
		} catch (NumberFormatException e) {
			e.printStackTrace();
			Log.println(e.toString());
			newNum = aDefaultValue;
		}
		return newNum;
	}

	static long getLong(final String aKey, final long aDefaultValue) {
		String strNum = PropertyManager.getProtery(aKey, Long.toString(aDefaultValue));
		long newNum = aDefaultValue;
		try {
			newNum = Long.parseLong(strNum);
		} catch (NumberFormatException e) {
			e.printStackTrace();
			Log.println(e.toString());
			newNum = aDefaultValue;
		}
		return newNum;
	}
	
	static String getProtery(final String aKey, final String aDefaultValue, final String aFilePath) {
		String newStr = null;
		try {
			FileInputStream fis = new FileInputStream(aFilePath);
			InputStreamReader input = new InputStreamReader(fis, CharSet);
			Properties p = new Properties();
			p.load(input);
			newStr = p.getProperty(aKey, aDefaultValue);
			p = null;
			input.close();
			input = null;
			fis.close();
			fis = null;
		} catch (Exception e) {
			e.printStackTrace();
			Log.println(e.toString());
			return aDefaultValue;
		}
		return newStr;
	}

	static void setProtery(String aKey, String aValue, final String aFilePath) {
		try {
		FileInputStream fis = new FileInputStream(aFilePath);
		FileOutputStream outputStream = new FileOutputStream(aFilePath);
		Properties p = new Properties();
		p.load(fis);
		p.setProperty(aKey, aValue);
		p.store(outputStream, null);
		} catch (Exception e) {
			e.printStackTrace();
			Log.println(e.toString());
		}
	}

}

// 超时定时器
// // 基于系统时间查询实现
class TimeOutTimer {
	final long IntervalMillis;
	long timeOutTimeMillis = 0;

	TimeOutTimer(final long aIntervalMillis) {
		this.IntervalMillis = aIntervalMillis;
		this.timeOutTimeMillis = System.currentTimeMillis() + this.IntervalMillis;
	}

	boolean getTimeOutState() {
		if (System.currentTimeMillis() > this.timeOutTimeMillis) {
			return true;
		} else {
			return false;
		}
	}

	void resetTimer() {
		this.timeOutTimeMillis = System.currentTimeMillis() + this.IntervalMillis;
	}
}

// ** 待改进

// 将所有涉及字符编码的地方改为UTF-8
// 可控线程：主循环线程，刷卡机节点监听线程，刷卡机节点线程，监视服务监听线程
// //?有没有线程可能卡住
// 日志整理，尽量都放在日志里，逐渐取消Log.println

// ??
// 程序启动前先看下文件是否齐全（配置文件，key文件）
// java 获取文件大小可用file类
// 获取当前编码

// ** 说明
// 服务内部文件操作统一采用“UTF-8”编码
